﻿using System;
using System.Net;
using System.Reflection;
using System.Security.Principal;
using System.ServiceModel;
using System.ServiceModel.Channels;
using Core.Helper;
using log4net;

namespace DataServer.Server
{
    public class CustomServiceAuthorizationManager : ServiceAuthorizationManager
    {
        private static readonly ILog _log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
        private bool isInit;
        private  bool _needLogin = true;
        protected override bool CheckAccessCore(OperationContext operationContext)
        {
            try
            {
                if (!isInit)
                {
                    isInit = true;
                    _needLogin = Core.Global.DataAccess.GetValueFromIni("权限控制", "登录操作", true);
                }
                if (!_needLogin)
                {
                    var woc0 = System.ServiceModel.Web.WebOperationContext.Current;
                    woc0?.OutgoingResponse.Headers.Add("Access-Control-Allow-Origin", "*");
                    return true;
                }
                   
                var woc = System.ServiceModel.Web.WebOperationContext.Current;
                if (woc == null)
                {
                    return false;
                }
                woc.OutgoingResponse.Headers.Add("Access-Control-Allow-Origin","*");
                var template = woc.IncomingRequest.UriTemplateMatch;
                if (template != null)
                {
                    if (template.RequestUri.ToString().Contains("localhost") ||
                        template.RequestUri.ToString().Contains("127.0.0.1") ||
                        template.RequestUri.ToString().Contains("user/login")||
                        template.RequestUri.ToString().Contains("user/logout"))
                    {
                        GenericIdentity identity = new GenericIdentity("");//必须插入一个Principal
                        operationContext.ServiceSecurityContext.AuthorizationContext.Properties["Principal"] = new GenericPrincipal(identity, null);
                        return true;
                    }
                }
                else
                {
                    return true;
                }
                //始终允许Metadata请求(mex)
                //if (operationContext.EndpointDispatcher.ContractName == ServiceMetadataBehavior.MexContractName &&
                //     operationContext.EndpointDispatcher.ContractNamespace == "http://schemas.microsoft.com/2006/04/mex" &&
                //     operationContext.IncomingMessageHeaders.Action == "http://schemas.xmlsoap.org/ws/2004/09/transfer/Get")
                //{
                //    GenericIdentity identity = new GenericIdentity("");//必须插入一个Principal
                //    operationContext.ServiceSecurityContext.AuthorizationContext.Properties["Principal"] = new GenericPrincipal(identity, null);
                //    return true;
                //}


                //访问的方法

                var auth = woc.IncomingRequest.Headers[HttpRequestHeader.Cookie];
                if (!string.IsNullOrEmpty(auth))
                {
                    string resolve = EncryptHelper.DecryptDES(auth, "12332156");
                    if (resolve != GetIpPort(operationContext))
                    {
                        woc.OutgoingResponse.StatusCode = HttpStatusCode.MethodNotAllowed;
                        return false;
                    }
                }
                else
                {
                    woc.OutgoingResponse.StatusCode = HttpStatusCode.MethodNotAllowed;
                    return false;
                }
                return true;
            }
            catch (Exception e)
            {
                _log.Debug("权限控制:"+e.Message);
                return false;
            }
           
        }
        private string GetIpPort(OperationContext context)
        {
            try
            {
                //获取传进的消息属性
                MessageProperties properties = context.IncomingMessageProperties;
                //获取消息发送的远程终结点IP和端口
                RemoteEndpointMessageProperty endpoint = properties[RemoteEndpointMessageProperty.Name] as RemoteEndpointMessageProperty;
                if (endpoint == null)
                    return "";
                return $"{endpoint.Address}";
            }
            catch
            {
            }
            return "";
        }
    }
}
